package com.tp2.etna.distribucion1.dao;

import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.mysql.jdbc.CallableStatement;
import com.tp2.etna.distribucion1.constante.GeneralConstante;
import com.tp2.etna.distribucion1.modelo.EntregaDetalleModel;
import com.tp2.etna.distribucion1.modelo.EntregaModel;
import com.tp2.etna.distribucion1.modelo.EstadoEntregaModel;

@Repository
public class EntregaDAOImpl implements EntregaDAO{

	@Autowired
    private DataSource dataSource;
 
    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }

	@Override
	public List<EntregaModel> listar(Date fechaInicio, Date fechaFin,
			int idCliente, int idEstadoEntrega) {
		
		
		 String query = "SELECT e.codigo"
						+ ",e.numero"
						+",e.fechaGeneracion"
						+",e.fechaEntrega"
						+",c.nombre"
						+",zd.descripcion"
						+",ee.descripcion"
						+",e.idEstadoEntrega"
						+" FROM Entrega e" 
						+" INNER JOIN Cliente c"
						+" ON e.idCliente = c.codigo"
						+" INNER JOIN ZonaDespacho zd"
						+" ON e.idZonaDespacho = zd.codigo"
						+" INNER JOIN EstadoEntrega ee"
						+" ON e.idEstadoEntrega = ee.codigo"
						+" WHERE (e.fechaGeneracion BETWEEN ? AND ?)";
		 
		 	if(idCliente > 0)
		 	{
		 		query = query 
		 				+" AND (e.idCliente = ?)";
						
		 		
		 	}
		 	
		 	if(idEstadoEntrega > 0)
		 	{
		 		query = query 
		 				+" AND e.idEstadoEntrega = ?";
		 	}
		 
		 
	        List<EntregaModel> lista = new ArrayList<EntregaModel>();
		    EntregaModel entrega = null;
	        Connection con = null;
	        PreparedStatement ps = null;
	        ResultSet rs = null;
	        try{
	            con = dataSource.getConnection();
	            ps = con.prepareStatement(query);
	            ps.setDate(1, fechaInicio);
	            ps.setDate(2, fechaFin);
	            
	            int contador = 3;
	            
	            if(idCliente > 0)
			 	{
	            	ps.setInt(contador, idCliente);
	            	contador++;
		           
			 	}
	            
	            if(idEstadoEntrega > 0)
			 	{
	            	 ps.setInt(contador, idEstadoEntrega);
			 	}
			 	          
	            rs = ps.executeQuery();
	            while(rs.next()){
	            	entrega = new EntregaModel();
	            	entrega.setCodigo(rs.getInt("codigo"));
	            	entrega.setNumero(rs.getString("numero"));
	            	entrega.setFechaGeneracion(rs.getDate("fechaGeneracion"));
	            	entrega.setFechaEntrega(rs.getDate("fechaEntrega"));
	            	entrega.setClienteNombre(rs.getString("nombre"));
	            	entrega.setZonaDespacho(rs.getString("zd.descripcion"));
	            	entrega.setEstadoEntrega(rs.getString("ee.descripcion"));
	            	entrega.setIdEstadoEntrega(rs.getInt("e.idEstadoEntrega"));
	                
	                lista.add(entrega);
	                
	            }
	            
	            
	            
	        }catch(SQLException e){
	            e.printStackTrace();
	        }finally{
	            try {
	                rs.close();
	                ps.close();
	                con.close();
	            } catch (SQLException e) {
	                e.printStackTrace();
	            }
	        }
	        return lista;
	}

	@Override
	public List<EstadoEntregaModel> listarEstado() {
		
		String query = "SELECT codigo"
				+ ",descripcion"
				+ ",abreviatura"
				+" FROM EstadoEntrega";				
					 
	     List<EstadoEntregaModel> lista = new ArrayList<EstadoEntregaModel>();
	     EstadoEntregaModel estadoEntrega = null;
	     
	     estadoEntrega = new EstadoEntregaModel();
    	 estadoEntrega.setCodigo(0);
    	 estadoEntrega.setDescripcion("[Todos]");
    	 estadoEntrega.setAbreviatura(GeneralConstante.CADENA_VACIA);
    	 
    	 lista.add(estadoEntrega);
	     
	     Connection con = null;
	     PreparedStatement ps = null;
	     ResultSet rs = null;
	     try{
	         con = dataSource.getConnection();
	         ps = con.prepareStatement(query);
	                   
	         rs = ps.executeQuery();
	         while(rs.next()){
	        	 estadoEntrega = new EstadoEntregaModel();
	        	 estadoEntrega.setCodigo(rs.getInt("codigo"));
	        	 estadoEntrega.setDescripcion(rs.getString("descripcion"));
	        	 estadoEntrega.setAbreviatura(rs.getString("abreviatura"));
	         
	             lista.add(estadoEntrega);
	             
	         }
	         
	     }catch(SQLException e){
	         e.printStackTrace();
	     }finally{
	         try {
	             rs.close();
	             ps.close();
	             con.close();
	         } catch (SQLException e) {
	             e.printStackTrace();
	         }
	     }
	     return lista;
		
	}

	@Override
	public List<EntregaDetalleModel> listarEntregaDetalle(int idEntrega) {
		
		String query = "SELECT ed.codigo"
				+ ",ed.nroItem"
				+",ed.idProducto"
				+",p.nombre"
				+",ed.cantidadEntregaProg"
				+",ed.cantidadEntregada"
				+",ed.cantidadRechazada"
				+",p.numero"
				+" FROM EntregaDetalle ed" 
				+" INNER JOIN Producto p"
				+" ON ed.idProducto = p.codigo"
				+" WHERE ed.idEntrega = ?";
 
		    List<EntregaDetalleModel> lista = new ArrayList<EntregaDetalleModel>();
		    EntregaDetalleModel entregaDetalle = null;
		    Connection con = null;
		    PreparedStatement ps = null;
		    ResultSet rs = null;
		    try{
		        con = dataSource.getConnection();
		        ps = con.prepareStatement(query);
		        ps.setInt(1, idEntrega);
		               
		        rs = ps.executeQuery();
		        while(rs.next()){
		        	entregaDetalle = new EntregaDetalleModel();
		        	entregaDetalle.setIdEntregaDetalle(rs.getInt("codigo"));
		        	entregaDetalle.setNroItem(rs.getInt("nroItem"));
		        	entregaDetalle.setIdProducto(rs.getInt("idProducto"));
		        	entregaDetalle.setProductoDescripcion(rs.getString("nombre"));
		        	entregaDetalle.setCantidadEntregaProg(rs.getInt("cantidadEntregaProg"));
		        	entregaDetalle.setCantidadEntregada(rs.getInt("cantidadEntregada"));
		        	entregaDetalle.setCantidadRechazada(rs.getInt("cantidadRechazada"));
		        	entregaDetalle.setProductoNumero(rs.getString("p.numero"));
		        		            
		            lista.add(entregaDetalle);
		            
		        }
		        
		    }catch(SQLException e){
		        e.printStackTrace();
		    }finally{
		        try {
		            rs.close();
		            ps.close();
		            con.close();
		        } catch (SQLException e) {
		            e.printStackTrace();
		        }
		    }
		    return lista;
		
	}

	@Override
	public boolean modificarFechaEntrega(Date fechaEntrega, int idEntrega) {
		
		String query = "UPDATE Entrega SET fechaEntrega=? WHERE codigo=?";
			
        Connection con = null;
        PreparedStatement ps = null;
        try{
            con = dataSource.getConnection();
            ps = con.prepareStatement(query);
            ps.setDate(1, fechaEntrega);
            ps.setInt(2, idEntrega);
            int out = ps.executeUpdate();
            if(out !=0){
            	return true;
            }
        }catch(SQLException e){
            e.printStackTrace();
        }finally{
            try {
                ps.close();
                con.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return false;
		
	}

	@Override
	public boolean eliminarEntrega(int idEntrega) {
		String query = "UPDATE Entrega SET idEstadoEntrega=4 WHERE codigo=?";
		
        Connection con = null;
        PreparedStatement ps = null;
        try{
            con = dataSource.getConnection();
            ps = con.prepareStatement(query);
            ps.setInt(1, idEntrega);
            int out = ps.executeUpdate();
            if(out !=0){
            	return true;
            }
        }catch(SQLException e){
            e.printStackTrace();
        }finally{
            try {
                ps.close();
                con.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return false;
	}
	
	public boolean generarEntregaFactura(Date fechaInicio, Date fechaFin)
	{
		
        Connection con = null;
        CallableStatement cs = null;
        boolean resultado = false;
        try{
            con = dataSource.getConnection();
            cs = (CallableStatement) con.prepareCall("{call generarEntregasFactura(?,?)}");
            cs.setDate(1, fechaInicio);
            cs.setDate(2, fechaFin);
            
            resultado = cs.execute();
            
        }catch(SQLException e){
            e.printStackTrace();
        }finally{
            try {
            	cs.close();
                con.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return resultado;
		
	}
	
	public boolean generarEntregaPedido(Date fechaInicio, Date fechaFin)
	{
		
        Connection con = null;
        CallableStatement cs = null;
        boolean resultado = false;
        try{
            con = dataSource.getConnection();
            cs = (CallableStatement) con.prepareCall("{call generarEntregasPedido(?,?)}");
            cs.setDate(1, fechaInicio);
            cs.setDate(2, fechaFin);
            
            resultado = cs.execute();
            
        }catch(SQLException e){
            e.printStackTrace();
        }finally{
            try {
            	cs.close();
                con.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return resultado;
		
	}
	
}
